package components
{
	import events.ChangeStateEvent;
	
	import flash.events.Event;
	import flash.events.MouseEvent;
	
	import model.Magazine;
	
	import mx.collections.ArrayCollection;
	import mx.controls.LinkButton;
	
	import spark.components.Image;
	import spark.components.Label;
	import spark.components.supportClasses.SkinnableComponent;
	import spark.events.IndexChangeEvent;

	public class MagazineView extends SkinnableComponent
	{
		[SkinPart(required="true")]
		public var currentPagesView:components.CurrentPagesView;
		
		[SkinPart(required="true")]
		public var bottomBar:components.PagesThumbnail;

		[SkinPart(required="true")]
		public var pageCount:Label;

		[SkinPart(required="true")]
		public var zoomedPage:Image;

		[SkinPart] public var zoomButton:LinkButton;
		[SkinPart] public var previewButton:LinkButton;
		[SkinPart] public var previousPageButton:LinkButton;
		[SkinPart] public var nextPageButton:LinkButton;
		[SkinPart] public var backButton:LinkButton;
		
		private var navigationBarStartIndex:int;
		private const MAX_NAVIGATION_BAR_ITEMS:int = 12;
		private var currentMagazine:model.Magazine;
		private var _currentPage:int;
		
		private function set currentPage(newValue:int):void
		{
			_currentPage = newValue;
			setPage(_currentPage);
		}
		
		private function get currentPage():int
		{
			return _currentPage;
		}

		override protected function partAdded(partName:String, instance:Object):void
		{
			super.partAdded(partName, instance);
			
			switch(instance)
			{
				case currentPagesView:
					setPage(currentPage);
					currentPagesView.leftPage.addEventListener(MouseEvent.CLICK, pageClickHandler);
					currentPagesView.rightPage.addEventListener(MouseEvent.CLICK, pageClickHandler);
					break;
				case bottomBar:
					bottomBar.leftButton.addEventListener(MouseEvent.CLICK, bottomBarHandler);
					bottomBar.rightButton.addEventListener(MouseEvent.CLICK, bottomBarHandler);
					bottomBar.pagesThumbnails.addEventListener(IndexChangeEvent.CHANGE, bottomBarHandler);
					updateNavigationBar();
					break;
				case previewButton:
					previewButton.addEventListener(MouseEvent.CLICK, switchSkinState);
					break;
				case zoomButton:
					zoomButton.addEventListener(MouseEvent.CLICK, switchSkinState);
					break;
				case nextPageButton:
					nextPageButton.addEventListener(MouseEvent.CLICK, nextPageButtonHandler);
					break;
				case previousPageButton:
					previousPageButton.addEventListener(MouseEvent.CLICK, previousPageButtonHandler);
					break;
				case backButton:
					backButton.addEventListener(MouseEvent.CLICK, backButtonHandler);
					break;
				case pageCount:
					pageCount.text = "Page " + (currentPage + 1) + "/" + currentMagazine.pages.length;
					break;
				case zoomedPage:
					zoomedPage.addEventListener(MouseEvent.CLICK, switchSkinState);
					break;
			}
		}
				
		private function setPage(newPage:int):void
		{
			if (currentPage % 2 == 0)
			{
				currentPagesView.leftPage.source = currentMagazine.pages.getItemAt(currentPage).source;
				if (currentMagazine.pages.length > currentPage + 1)
					currentPagesView.rightPage.source = currentMagazine.pages.getItemAt(currentPage + 1).source;
				else currentPagesView.rightPage.source = null;
				currentPagesView.leftPage.alpha = 1;
				currentPagesView.rightPage.alpha = 0.5;
			}
			else
			{
				currentPagesView.leftPage.source = currentMagazine.pages.getItemAt(currentPage - 1).source;
				currentPagesView.rightPage.source = currentMagazine.pages.getItemAt(currentPage).source;
				currentPagesView.leftPage.alpha = 0.5;
				currentPagesView.rightPage.alpha = 1;
			}
			if (pageCount)
				pageCount.text = "Page " + (currentPage + 1) + "/" + currentMagazine.pages.length;
		}
		
		public function initMagazineViewer(newMagazine:model.Magazine):void
		{
			skin.currentState = "DefaultState";
			currentMagazine = newMagazine;
			currentPage = 0;
			navigationBarStartIndex = 0;
			if (bottomBar) updateNavigationBar();
		}
		
		private function updateNavigationBar():void
		{
			bottomBar.pagesThumbnails.dataProvider = new ArrayCollection(currentMagazine.pages.toArray().slice(navigationBarStartIndex, navigationBarStartIndex + MAX_NAVIGATION_BAR_ITEMS));
		}
		
		protected function switchSkinState(e:Event):void
		{
			if (skin.currentState == "DefaultState")
			{
				skin.currentState = "ZoomState";
				zoomedPage.source = currentMagazine.pages.getItemAt(currentPage).source;
			}
			else skin.currentState = "DefaultState";
				
		}
		
		protected function previousPageButtonHandler(e:Event):void
		{
			currentPage = (currentPage - 1 + currentMagazine.pages.length) % currentMagazine.pages.length;
		}
		
		protected function nextPageButtonHandler(e:Event):void
		{
			currentPage = (currentPage + 1) % currentMagazine.pages.length;
		}

		protected function bottomBarHandler(e:Event):void
		{
			switch (e.currentTarget)
			{
				case bottomBar.pagesThumbnails:
					currentPage = e.currentTarget.selectedIndex + navigationBarStartIndex;
					break;
				case bottomBar.leftButton:
					if (navigationBarStartIndex > 0)
					{
						--navigationBarStartIndex;
						updateNavigationBar();
					}
					break;
				case bottomBar.rightButton:
					if (navigationBarStartIndex < currentMagazine.pages.length - MAX_NAVIGATION_BAR_ITEMS)
					{
						++navigationBarStartIndex;
						updateNavigationBar();
					}
					break;
			}
		}
		
		protected function backButtonHandler(e:MouseEvent):void
		{
			dispatchEvent(new ChangeStateEvent(ChangeStateEvent.CHANGE_STATE, null));
		}
		
		protected function pageClickHandler(e:MouseEvent):void
		{
			switch (e.currentTarget)
			{
				case currentPagesView.leftPage:
					if (currentPage == currentPage - (currentPage % 2))
						switchSkinState(e);
					else currentPage = currentPage - (currentPage % 2);
					break;
				case currentPagesView.rightPage:
					if (currentPagesView.rightPage.source)
					{
						if (currentPage == currentPage + 1 - (currentPage % 2))
							switchSkinState(e);
						else currentPage = currentPage + 1 - (currentPage % 2);
					}
					break;
			}
		}
	}
}